package cn.tsvtc.shop.service.impl;

import cn.tsvtc.shop.constant.RedisConstant;
import cn.tsvtc.shop.pojo.Order;
import cn.tsvtc.shop.service.PayService;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * @author: Athena
 * @date: 2020/11/7 11:25
 * @description:
 */
@Service
public class PayServiceImpl implements PayService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${aliPublicKey}")
    String aliPublicKey;

    @Value("${myPrivateKey}")
    String myPrivateKey;

    @Value("${myPublicKey}")
    String myPublicKey;

    /**
     * 创建支付宝form表单
     *
     * @param order
     * @return
     */
    @Override
    public String createForm(Order order) {
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipaydev.com/gateway.do",   //支付网关
                "2016103100781634",   //商家ID
                //商家私钥
                myPrivateKey,
                "JSON",   //格式
                "utf-8",  //编码
                //支付宝公钥
                aliPublicKey,
                //签名类型
                "RSA2");  //获得初始化的AlipayClient

        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); //创建API对应的request

        alipayRequest.setReturnUrl("http://nat.tsvtc.cn/pay/pay/success");           //支付宝支付成功后回调接口
        alipayRequest.setNotifyUrl("http://nat.tsvtc.cn/pay/pay/notifyurl?orderno=" + order.getId() ); //在公共参数中设置回跳和通知地址
        alipayRequest.setBizContent("{" +
                //订单编号
                "    \"out_trade_no\":" + order.getId() + "," +
                "    \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
                //支付金额
                "    \"total_amount\":"+order.getAmount()+"," +
                "    \"subject\":\"来自tsvtc的订单\"," +
                "    \"body\":\""+order.getAccount()+"的订单\"," +
                "    \"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\"," +
                "    \"extend_params\":{" +
                "    \"sys_service_provider_id\":\"2088511833207846\"" +
                "    }" +
                "  }"); //填充业务参数
        String form="";
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody();  //调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return form;
    }

    /**
     * 验证
     *
     * @param map
     * @param orderId
     * @return
     */
    @Override
    public boolean validate(Map map, String orderId)  {
        try {
            Object o = redisTemplate.opsForValue().get(RedisConstant.ORDER + orderId);
            Order order= (Order) o;
            //将异步通知中收到的所有参数都存放到 map 中
            //1.判断支付接口是不是支付宝调用的
            boolean signVerified = AlipaySignature.rsaCheckV1(
                    map,
                    aliPublicKey,
                    "utf-8",
                    "RSA2");
            //调用SDK验证签名

           /* boolean  signVerified = AlipaySignature.rsaCheckV1(
                    paramsMap,
                    "",
                    "utf-8",
                    "RSA2");  //调用SDK验证签名*/
            //2.是支付宝调用的
            if (signVerified){
                // TODO 验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
                System.out.println("验签成功。。。。。");
                //商户需要验证该通知数据中的 out_trade_no 是否为商户系统中创建的订单号；
                String out_trade_no = (String) map.get("out_trade_no");
                if(!out_trade_no.equalsIgnoreCase(orderId)) {
                    System.out.println("验签失败-> 订单号不正确");
                    return false;
                    //response.getWriter().write("failure");
                    //return;
                } else {
                    System.out.println("---->订单号正确，6666");
                }
                //判断 total_amount 是否确实为该订单的实际金额（即商户订单创建时的金额）；
                String total_amount = (String) map.get("total_amount");
                double m = Double.parseDouble(total_amount);
                if(m != order.getAmount().doubleValue()) {
                    System.out.println("验签失败-> 金额不正确");
                    return false;
                    //response.getWriter().write("failure");
                    //return;
                } else {
                    System.out.println("---->金额正确，6666");
                }
                //验证 app_id 是否为该商户本身。
                String app_id = (String) map.get("app_id");
                if(!app_id.equalsIgnoreCase("2016103100781634")) {
                    System.out.println("验签失败-> appId不正确");
                    return false;
                    //response.getWriter().write("failure");
                    //return;
                } else {
                    System.out.println("---->appId正确，6666");
                }

                //校验通知中的 seller_id（或者 seller_email) 是否为 out_trade_no 这笔单据的对应的操作方（有的时候，一个商户可能有多个 seller_id/seller_email）；
                //response.getWriter().write("success");

            } else {
                // TODO 验签失败则记录异常日志，并在response中返回failure.
                System.out.println("验签失败，不是支付宝的调用的接口......");
                //response.getWriter().write("failure");
                return false;
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}
